import { readJSONSync, readdirSync, writeJSONSync } from 'fs-extra';
import { resolve, join } from 'path';

import chalk from 'chalk';
import { e } from 'unocss';

const log = console.log;

interface IPkgFile {
  path: string;
  json: {
    name: string;
    version: string;
    dependencies: { [key: string]: string };
    devDependencies: { [key: string]: string };
  };
}
log(chalk.blue('==========>开始精简=============='));
/**
 * 子项目文件夹目录列表
 */
const pkgDirs = ['packages'];
const rootDir = join(__dirname, '..');
/**
 * 读取文件路径和内容
 * @param parentPah 上级目录
 * @returns {IPkgFile}
 */
const findPkgJson = (parentPah: string): IPkgFile => {
  const filePath = join(parentPah, 'package.json');
  return {
    path: filePath,
    json: readJSONSync(filePath, 'utf-8'),
  };
};
/**
 * 获取工作空间配置
 */
const rootPkgJson = findPkgJson(join(__dirname, '..'));
/**
 * 获取子项目配置
 */
const pkgList: IPkgFile[] = [];
pkgDirs.forEach((dir) => {
  const currentPath = join(rootDir, dir);
  const childDirs = readdirSync(join(rootDir, dir));
  if (Array.isArray(childDirs) && childDirs.length) {
    childDirs.forEach((childDir) => {
      const pkgJson = findPkgJson(join(currentPath, childDir));
      pkgJson && pkgList.push(pkgJson);
    });
  }
});
/**
 * 需要更新的json 列表
 */
const needUpdate: IPkgFile[] = [];
/**
 * 去重的方法
 * @param pkg
 */

const pushFunc = (pkg: IPkgFile) => {
  const has = needUpdate.findIndex((item) => item.path === pkg.path);
  if (has === -1) {
    needUpdate.push(pkg);
  } else {
    needUpdate.splice(has, 1, pkg);
  }
};

const fetchRootDeps = (
  prevPkg: IPkgFile,
  currentPkg: IPkgFile,
  keyName: 'dependencies' | 'devDependencies',
) => {
  Object.entries(prevPkg.json[keyName]).forEach(([key, value]) => {
    if (currentPkg.json[keyName][key]) {
      if (currentPkg.json[keyName][key] === value) {
        delete currentPkg.json[keyName][key];
        pushFunc(currentPkg);
      }
    }
  });
};

const fetchChildDeps = (
  first: IPkgFile,
  keyName: 'dependencies' | 'devDependencies',
) => {
  pkgList.forEach((pkg) => {
    Object.entries(first.json[keyName]).forEach(([key, value]) => {
      if (pkg.json[keyName][key]) {
        if (pkg.json[keyName][key] === value) {
          delete first.json[keyName][key];
          pushFunc(first);
          delete pkg.json[keyName][key];
          pushFunc(pkg);
          !rootPkgJson.json[keyName][key] &&
            (rootPkgJson.json[keyName][key] = value);
        }
      }
    });
  });
};

/**
 * 将工作空间和子项目依赖去重
 */
const fetchRootAndChildren = () => {
  pkgList.forEach((pkg) => {
    fetchRootDeps(rootPkgJson, pkg, 'dependencies');
    fetchRootDeps(rootPkgJson, pkg, 'devDependencies');
  });
};
fetchRootAndChildren();
/**
 * 子项目依赖去重
 */

const fetchChildren = () => {
  const first = pkgList.shift();
  if (first && pkgList.length) {
    fetchChildDeps(first, 'dependencies');
    fetchChildDeps(first, 'devDependencies');
  }
  if (pkgList.length) {
    fetchChildren();
  }
};

fetchChildren();

if (needUpdate.length) {
  needUpdate.forEach((pkg) => {
    writeJSONSync(pkg.path, pkg.json, { spaces: 2 });
  });
}

log(chalk.green('==========>精简完毕=============='));
